
// XOR256Block.h

#ifndef __XOR256BLOCK_H__
#define __XOR256BLOCK_H__


//TO_BE_EXPORTED

//Typical DISCLAIMER:
//The code in this project is Copyright (C) 2003 by George Anescu. You have the right to
//use and distribute the code in any way you see fit as long as this paragraph is included
//with the distribution. No warranties or claims are made as to the validity of the
//information and code contained herein, so use it at your own risk.

#include "bOSArcfourPRNG.h"
#include "bOSMethod.h"
#include <memory>

using namespace std;

class BOS_API CXOR256Block : public IMethod
{
private:
	enum { KEY_MAX = 256 };
	enum { BLOCK_MAX = 256 };
	enum { BUFF_LEN=1024 };

public:
	//CONSTRUCTOR
	CXOR256Block();

	//DESTRUCTOR
	~CXOR256Block();

	//Expand a user-supplied key material into a session key.
	// keydata - The key material expanded to 256 bytes user-key to use.
	// keydatalength - how much to take from keydata
	// chain - initial chain block for CBC and CFB modes.
	// iMode - Chaining Operation Mode
	// iPadding - Padding Mode
	// key length is fixed to 256
	void Initialize(char const* keydata, int keydatalength, char const* chain=sm_chain0,
		int blockSize=16, int iORounds=4, int iIRounds=4, int iMode=ECB, int iPadding=ZEROES);
	//Resetting the Initialization Vector
	void ResetChain();
	//Encryption for a string of chars
	void Encrypt(char const* in, char* result, size_t n);
	//Decryption for a string of chars
	void Decrypt(char const* in, char* result, size_t n);
	//Encryption for a File
	void EncryptFile(string const& rostrFileIn, string const& rostrFileOut);
	//Decryption for a File
	void DecryptFile(string const& rostrFileIn, string const& rostrFileOut);

private:
	//Compute Signature
	void Signature(char* pcSig);
	void EncryptDirect(unsigned char* pucBlock, unsigned char const* pucXOR, unsigned char const* puc256);
	void EncryptDirect1(unsigned char* pucBlock, unsigned char const* pucXOR, unsigned char const* puc256);
	void EncryptReverse(unsigned char* pucBlock, unsigned char const* pucXOR, unsigned char const* puc256);
	void EncryptReverse1(unsigned char* pucBlock, unsigned char const* pucXOR, unsigned char const* puc256);
	void DecryptDirect(unsigned char* pucBlock, unsigned char const* pucXOR, unsigned char const* puc256);
	void DecryptDirect1(unsigned char* pucBlock, unsigned char const* pucXOR, unsigned char const* puc256);
	void DecryptReverse(unsigned char* pucBlock, unsigned char const* pucXOR, unsigned char const* puc256);
	void DecryptReverse1(unsigned char* pucBlock, unsigned char const* pucXOR, unsigned char const* puc256);
	void EncryptBlock(unsigned char* pucBlock);
	void DecryptBlock(unsigned char* pucBlock);

	CArcfourPRNG m_oArcfourPRNG;
	int m_iBlockSize;
	int m_iBlockSize1; //m_iBlockSize-1
	//Internal Rounds
	int m_iIRounds;
	int m_iIRounds1; //m_iIRounds-1
	//External Rounds
	int m_iORounds;
	int m_iORounds1; //m_iORounds-1
	int m_iProd; //m_iBlockSize*m_iIRounds
	int m_iDelta; //(m_iORounds-1)*m_iProd
	unsigned char* m_pucXOR;
	unsigned char* m_puc256;
	//Key
	auto_ptr<char> m_apKey;
	//Chain Block
	auto_ptr<char> m_apchain0;
	auto_ptr<char> m_apchain;
	auto_ptr<unsigned char> m_apTemp;
	static char const* sm_szErrorMsgXB1;
	static char const* sm_szErrorMsgXB2;

public:
	//Null chain
	static char const sm_chain0[BLOCK_MAX]; //Max blocksize assumed
};

#endif // __XOR256BLOCK_H__

